import logging
import math
from typing import Optional, List

from fastapi import APIRouter, Depends, Query, Path
from pydantic import Field, BaseModel
from sqlalchemy import text
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session
from commons.BaseResponse import BaseResponse
from commons.PaginationBase import PaginationBase
from datebase import get_db
from utils.EncryptionUtil import oauth2_scheme, EncryptionMiddleware

part_info_router = APIRouter(prefix="/part/partInfo", tags=["备件资料管理"], dependencies=[Depends(oauth2_scheme)])


class SparePartInfoSearch(PaginationBase):
    # 筛选条件
    fpartname: Optional[str] = Field("", description="备件名称(支持前缀匹配)")
    fclassstno: Optional[str] = Field("", description="分类编号")


@part_info_router.get("/list", summary="备件资料查询接口")
def list_part_info(search: SparePartInfoSearch = Query(), db: Session = Depends(get_db)):
    param = {}
    sql = "select count(1) from s_ts_part_info where 1=1"
    if search.fpartname != "":
        sql = sql + " and fpartname like concat('%', :fpartname ,'%')"
        param["fpartname"] = search.fpartname
    if search.fclassstno != "":
        sql = sql + " and fclassstno = :fclassstno "
        param["fclassstno"] = search.fclassstno
    count = db.execute(text(sql), param).scalar()

    param = {}
    sql = "select fpartid,fpartno,fpartname,fclassstno,funit,fbrand,fspec,"
    sql = sql + " fuseyear,fimage,fpanel,fbarcode,fbuyprice,fupddate,foperator"
    sql = sql + " from s_ts_part_info where 1=1"
    if search.fpartname != "":
        sql = sql + " and fpartname like concat('%', :fpartname ,'%')"
        param["fpartname"] = search.fpartname
    if search.fclassstno != "":
        sql = sql + " and fclassstno = :fclassstno "
        param["fclassstno"] = search.fclassstno
    if search.order == "desc":
        sql = sql + " order by  fclassstno,fpartno desc "
    else:
        sql = sql + " order by  fclassstno,fpartno "
    sql = sql + " limit :limit offset :offset "
    param["offset"] = search.offset
    param["limit"] = search.limit
    data = db.execute(text(sql), param).fetchall()

    data_list = []
    for key in range(len(data)):
        d1 = {}
        d1['fpartid'] = data[key][0]
        d1['fpartno'] = data[key][1]
        d1['fpartname'] = data[key][2]
        d1['fclassstno'] = data[key][3]
        d1['funit'] = data[key][4]
        d1['fbrand'] = data[key][5]
        d1['fspec'] = data[key][6]
        d1['fuseyear'] = data[key][7]
        d1['fimage'] = data[key][8]
        d1['fpanel'] = data[key][9]
        d1['fbarcode'] = data[key][10]
        d1['fbuyprice'] = data[key][11]
        d1['fupddate'] = data[key][12]
        d1['foperator'] = data[key][13]
        data_list.append(d1)

    info_dict = {"list": data_list,
                 "limit": search.limit,
                 "page": search.pageIndex,
                 "pages": (count + search.limit - 1) // search.limit,
                 "total": count}
    return BaseResponse.success(data=info_dict)


class SparePartInfoCreate(BaseModel):
    """备件资料新增请求参数"""
    fpartno: str = Field(..., description="备件编号")
    fpartname: str = Field(..., description="备件名称")
    fclassstno: str = Field(..., description="分类编号")
    funit: Optional[str] = Field("", description="单位")
    fbrand: Optional[str] = Field("", description="品牌")
    fspec: Optional[str] = Field("", description="规格")
    fuseyear: int = Field(0, description="使用年限，默认0")
    fpanel: int = Field(..., description="面板标识")
    fbarcode: Optional[str] = Field("", description="条形码")
    fbuyprice: float = Field(0.0, description="购买单价，默认0.0")
    fupddate: str = Field(..., description="更新日期(格式需与数据库存储一致)")
    foperator: str = Field(..., description="操作人ID")


@part_info_router.post("/create", summary="备件资料新增接口")
def create_part_info(create: SparePartInfoCreate, db: Session = Depends(get_db)):
    try:
        with db.begin():
            sql = "select fpartno from s_ts_part_info where fpartno= :fpartno "
            data = db.execute(text(sql), {"fpartno": create.fpartno}).fetchall()

            if len(data) > 0:
                return BaseResponse.error(message="编号已存在")
            else:
                sql = "insert into s_ts_part_info(fpartno,fpartname,fclassstno,funit,fbrand,fspec,fuseyear,fpanel,fbarcode,fbuyprice,fupddate,foperator)"
                sql = sql + " values( :fpartno , :fpartname , :fclassstno , :funit , :fbrand , :fspec , :fuseyear , :fpanel , :fbarcode , :fbuyprice , :fupddate , :foperator );"
                db.execute(text(sql), {
                    "fpartno": create.fpartno,
                    "fpartname": create.fpartname,
                    "fclassstno": create.fclassstno,
                    "funit": create.funit,
                    "fbrand": create.fbrand,
                    "fspec": create.fspec,
                    "fuseyear": create.fupddate,
                    "fpanel": create.fpanel,
                    "fbarcode": create.fbarcode,
                    "fbuyprice": create.fbuyprice,
                    "fupddate": create.fupddate,
                    "foperator": create.foperator
                })
                data = {"fbarcode": create.fbarcode
                    , "fbrand": create.fbrand
                    , "fbuyprice": create.fbuyprice
                    , "fclassstno": create.fclassstno
                    , "fimage": None
                    , "fpanel": create.fpanel
                    , "fpartid": 0  # 应该获取当前值
                    , "fpartname": create.fpartname
                    , "fpartno": create.fpartno
                    , "fspec": create.fspec
                    , "funit": create.funit
                    , "fuseyear": create.fuseyear
                    , "fupddate": create.fupddate
                    , "foperator": create.foperator
                        }
                return BaseResponse.success(data=data)
    except SQLAlchemyError as e:
        # 发生异常时自动回滚
        db.rollback()
        # 记录错误日志
        logging.error(f"数据库错误: {str(e)}")
        # 返回错误响应
        return BaseResponse.error(message="数据库操作失败")
    except Exception as e:
        db.rollback()
        logging.error(f"未知错误: {str(e)}")
        return BaseResponse.error(message="令牌过期")


@part_info_router.post("/update", summary="备件资料修改接口")
def update_part_info(update: SparePartInfoCreate, db: Session = Depends(get_db)):
    try:
        with db.begin():
            sql = "update s_ts_part_info"
            sql = sql + " set fbarcode= :fbarcode ,fbrand= :fbrand "
            sql = sql + ",fbuyprice= :fbuyprice ,fclassstno= :fclassstno "
            sql = sql + ",fpanel= :fpanel ,fpartname= :fpartname "
            sql = sql + ",fspec= :fspec ,funit= :funit ,fuseyear= :fuseyear "
            sql = sql + ",fupddate= :fupddate ,foperator= :foperator "
            sql = sql + " where fpartno= :fpartno "
            db.execute(text(sql), {
                "fbarcode": update.fbarcode,
                "fbrand": update.fbrand,
                "fbuyprice": update.fbuyprice,
                "fclassstno": update.fclassstno,
                "fpanel": update.fpanel,
                "fpartname": update.fpartname,
                "fspec": update.fspec,
                "funit": update.funit,
                "fuseyear": update.fuseyear,
                "fupddate": update.fupddate,
                "foperator": update.foperator,
                "fpartno": update.fpartno
            })
            return BaseResponse.success()
    except SQLAlchemyError as e:
        # 发生异常时自动回滚
        db.rollback()
        # 记录错误日志
        logging.error(f"数据库错误: {str(e)}")
        # 返回错误响应
        return BaseResponse.error(message="数据库操作失败")
    except Exception as e:
        db.rollback()
        logging.error(f"未知错误: {str(e)}")
        return BaseResponse.error(message="令牌过期")


@part_info_router.post("/delete/{fpartid}", summary="备件资料删除接口")
def delete_part_info(fpartid: str = Path(description="备件资料编号"), db: Session = Depends(get_db)):
    try:
        with db.begin():
            sql = "delete from s_ts_part_info where fpartid= :fpartid "
            param = {"fpartid": fpartid}
            db.execute(text(sql), param)

    except SQLAlchemyError as e:
        # 发生异常时自动回滚
        db.rollback()
        # 记录错误日志
        logging.error(f"数据库错误: {str(e)}")
        # 返回错误响应
        return BaseResponse.error(message="数据库操作失败")
    except Exception as e:
        db.rollback()
        logging.error(f"未知错误: {str(e)}")
        return BaseResponse.error(message="令牌过期")
